package com.hgvip.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import redis.clients.jedis.JedisPoolConfig;

import java.util.ArrayList;
import java.util.List;

/**
 * @author arnold.zhu
 * @date 5/17/2017
 */
@Configuration
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private int port;
    @Value("${spring.redis.pool.maxTotal}")
    private int maxTotal;
    @Value("${spring.redis.pool.maxIdle}")
    private int maxIdle;
    @Value("${spring.redis.pool.minIdle}")
    private int minIdle;

    @Value("${spring.redis.mode}")
    private String mode;

    @Value("${spring.redis.maxRedirects}")
    private int maxRedirects;
    @Value("${spring.redis.clusters}")
    private String clusters;

    @Value("${spring.redis.sentinel.master}")
    private String sentinelMaster;
    @Value("${spring.redis.sentinels}")
    private String sentinels;

    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig pool = new JedisPoolConfig();
        pool.setMaxIdle(maxIdle);
        pool.setMaxTotal(maxTotal);
        pool.setMinIdle(minIdle);
        return pool;
    }

    @Bean
    public RedisClusterConfiguration redisClusterConfiguration() {
        RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
        redisClusterConfiguration.setMaxRedirects(maxRedirects);
        List<RedisNode> redisNodes = new ArrayList<>();
        String[] hosts = clusters.split(",");
        for (int i = 0; i < hosts.length; i++) {
            String[] host_port = hosts[i].split(":");
            redisNodes.add(new RedisNode(host_port[0], Integer.parseInt(host_port[1])));
        }
        redisClusterConfiguration.setClusterNodes(redisNodes);
        return redisClusterConfiguration;
    }

    @Bean
    public RedisSentinelConfiguration redisSentinelConfiguration() {
        RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();
        redisSentinelConfiguration.setMaster(sentinelMaster);
        List<RedisNode> redisNodes = new ArrayList<>();
        String[] hosts = sentinels.split(",");
        for (int i = 0; i < hosts.length; i++) {
            String[] host_port = hosts[i].split(":");
            redisNodes.add(new RedisNode(host_port[0], Integer.parseInt(host_port[1])));
        }
        redisSentinelConfiguration.setSentinels(redisNodes);
        return redisSentinelConfiguration;
    }

    @Bean
    public JedisConnectionFactory jedisConnectionFactory() {
        JedisConnectionFactory factory;
        String cluster = "cluster", single = "single";
        if (cluster.equals(mode)) {
            factory = new JedisConnectionFactory(redisClusterConfiguration(), jedisPoolConfig());
        } else if (single.equals(mode)) {
            factory = new JedisConnectionFactory(jedisPoolConfig());
            factory.setHostName(host);
            factory.setPort(port);
            factory.setUsePool(true);
        } else {
            factory = new JedisConnectionFactory(redisSentinelConfiguration(), jedisPoolConfig());
        }
        return factory;
    }

    @Bean
    public RedisTemplate redisTemplate() {
        RedisTemplate template = new RedisTemplate();
        template.setConnectionFactory(jedisConnectionFactory());
        return template;
    }

}
